package com.atguigu.gulimail.product.exception;


import com.atguigu.common.exception.BizCodeEnume;
import com.atguigu.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.HashMap;
import java.util.Map;

/*统一异常处理类*/
//springMVC提供@ControllerAdvice注解，里面指定处理异常类的
//处理异常的消息，以json的数据类型返回回去，添加一个ResponseBody注解 + ControllerAdvice注解，等价于RestController注解

@RestControllerAdvice(basePackages = "com.atguigu.gulimail.product.controller")
@Slf4j
public class GulimailExceptionControllerAdvice {
    /*@ExceptionHandler这个注解作用告诉spring处理什么类型的异常*/
    //1处理数据校验的异常 处理任何异常 通过测试，校验接口异常MethodArgumentNotValidException类型
    @ExceptionHandler(value =  MethodArgumentNotValidException.class)
    public R handleValidException(MethodArgumentNotValidException e){
        //打印日志  e.getMessage()回去异常消息，e.getClass()获取异常的类型
        log.error("数据校验出现问题{}，异常类型:{}",e.getMessage(),e.getClass());
        //获取BindingResult类型对象，从该对象获取异常类型，异常消息
        BindingResult bindingResult = e.getBindingResult();
        //自定义Map类型，封装异常
        Map<String,String>  errorMap = new HashMap<>();
        //通过bindingResult对象中进行获取出现校验异常的字段的异常类型和异常的消息
        bindingResult.getFieldErrors().forEach( (item) -> {
            //遍历数据校验异常的字段信息和异常类型
            String errorField = item.getField();
            String errorMessage = item.getDefaultMessage();
            //封装到map中
            errorMap.put(errorField,errorMessage);
        }  );
        return R.error(BizCodeEnume.VAILD_EXCEPTION.getCode(),BizCodeEnume.VAILD_EXCEPTION.getMsg()).put("data",errorMap);
    }

    //其他的通用异常处理交给这个异常进行处理
    @ExceptionHandler(value= Throwable.class)
    public R handleException(Throwable throwable){
        //直接打印通用的错误的信息
        log.error("错误: ",throwable);
        return R.error();
    }
}
